// ==========================================================================
// gin-sns自动生成业务逻辑层相关代码，只生成一次，按需修改,再次生成不会覆盖.
// date：2021-02-21 13:45:54 +0800 CST
// path: app/service/module/usertoken_service.go
// author：jon
// ==========================================================================
package module

import (
	"errors"
	"gin-sns/app/dao/module/usertoken"
	"gin-sns/app/model"
	userModel "gin-sns/app/model/module/user"
	usertokenModel "gin-sns/app/model/module/usertoken"
	"time"

	"github.com/gin-gonic/gin"

	"gin-sns/app/ginframe/tools"
	"gin-sns/app/ginframe/utils/convert"
	"gin-sns/app/ginframe/utils/page"
)

var UsertokenService = newUsertokenService()

func newUsertokenService() *usertokenService {
	return &usertokenService{}
}

type usertokenService struct {
}

//根据主键查询数据
func (s *usertokenService) SelectRecordById(id int64) (*usertokenModel.Entity, error) {
	return usertoken.UsertokenDao.SelectById(id)
}

//
func (s *usertokenService) SelectRecordsIn(idarr []int64) ([]usertokenModel.Entity, error) {

	list, err := usertoken.UsertokenDao.FindIn("id", idarr)
	if list != nil && len(list) > 0 {
		err = errors.New("not found")
		list = nil
	}
	return list, err
}

func (s *usertokenService) GetByToken(token string) *usertokenModel.Entity {
	entity := &usertokenModel.Entity{Token: token}
	have, err := usertoken.UsertokenDao.FindOne(entity)
	if !have {
		err = errors.New("not found")
	}
	if err != nil {
		return nil
	}
	return entity
}

//根据主键删除数据
func (s *usertokenService) DeleteRecordById(id int64) bool {
	return usertoken.UsertokenDao.DeleteById(id)
}

//批量删除数据记录
func (s *usertokenService) DeleteRecordByIds(ids string) int64 {
	ida := convert.ToInt64Array(ids, ",")
	result, err := usertoken.UsertokenDao.DeleteBatch(ida...)
	if err != nil {
		return 0
	}
	return result
}

//添加数据
func (s *usertokenService) AddSave(req *usertokenModel.AddReq, ctx *gin.Context) (int64, error) {
	var entity usertokenModel.Entity

	//entity.Id = req.Id
	entity.UserId = req.UserId
	entity.Token = req.Token
	entity.ExpiredAt = req.ExpiredAt
	entity.Status = req.Status
	entity.CreateTime = time.Now()
	//entity.CreateBy = ""

	//user := system.UserService.GetProfile(ctx)

	//if user != nil {
	//	entity.CreateBy = user.LoginName
	//}

	_, err := usertoken.UsertokenDao.Insert(&entity)
	return entity.Id, err
}

//修改数据
func (s *usertokenService) EditSave(req *usertokenModel.EditReq, ctx *gin.Context) (int64, error) {
	entity := &usertokenModel.Entity{Id: req.Id}
	ok, err := usertoken.UsertokenDao.FindOne(entity)

	if err != nil {
		return 0, err
	}

	if !ok {
		return 0, errors.New("数据不存在")
	}

	entity.UserId = req.UserId
	entity.Token = req.Token
	entity.ExpiredAt = req.ExpiredAt
	entity.Status = req.Status
	//entity.UpdateTime = time.Now()
	//entity.UpdateBy = ""

	//user := system.UserService.GetProfile(ctx)

	//if user == nil {
	//	entity.UpdateBy = user.LoginName
	//}

	return usertoken.UsertokenDao.Update(entity)
}

//根据条件查询数据
func (s *usertokenService) SelectListAll(params *usertokenModel.SelectPageReq) ([]usertokenModel.Entity, error) {
	return usertoken.UsertokenDao.SelectListAll(params)
}

//根据条件分页查询数据
func (s *usertokenService) SelectListByPage(params *usertokenModel.SelectPageReq) ([]usertokenModel.Entity, *page.Paging, error) {
	return usertoken.UsertokenDao.SelectListByPage(params)
}

// 导出excel
func (s *usertokenService) Export(param *usertokenModel.SelectPageReq) (string, error) {
	head := []string{"", "用户id", "令牌", "过期时间", "0未审核 1正常状态 2审核未通过 3删除", "创建时间"}
	col := []string{"id", "user_id", "token", "expired_at", "status", "create_time"}
	return usertoken.UsertokenDao.SelectListExport(param, head, col)
}

// 获取当前登录用户
func (s *usertokenService) GetCurrent(c *gin.Context) *userModel.Entity {
	token := s.GetUserToken(c)
	//userToken := cache.UserTokenCache.Get(token) //todo cache
	userToken := s.GetByToken(token)
	// 没找到授权
	if userToken == nil || userToken.Status == model.UserTokenStatusDisabled {
		return nil
	}
	// 授权过期
	if userToken.ExpiredAt <= time.Now().Unix() {
		return nil
	}
	//return cache.UserCache.Get(userToken.UserId) //todo cache
	entity, err := UserService.SelectRecordById(userToken.UserId)
	if err != nil {
		return nil
	}
	return entity
}

// 退出登录
func (s *usertokenService) Signout(c *gin.Context) error {
	token := s.GetUserToken(c)
	userToken := s.GetByToken(token)
	if userToken == nil {
		return nil
	}

	editReq := &usertokenModel.EditReq{
		Id:        userToken.Id,
		UserId:    userToken.UserId,
		Token:     userToken.Token,
		ExpiredAt: userToken.ExpiredAt,
		Status:    model.UserTokenStatusDisabled,
	}

	_, err := s.EditSave(editReq, nil)
	return err
}

// 从请求体中获取UserToken
func (s *usertokenService) GetUserToken(c *gin.Context) string {
	userToken := c.GetString("userToken")
	if len(userToken) > 0 {
		return userToken
	}
	return c.GetHeader("X-User-Token")
}

// 生成
func (s *usertokenService) Generate(userId int64) (string, error) {
	token := tools.Uuid()
	expiredAt := time.Now().Add(time.Hour * 24 * 7) // 7天后过期
	addReq := &usertokenModel.AddReq{
		UserId:    userId,
		Token:     token,
		ExpiredAt: tools.Timestamp(expiredAt),
		Status:    model.UserTokenStatusOk,
	}

	_, err := s.AddSave(addReq, nil)
	if err != nil {
		return "", err
	}
	return token, nil
}

// 禁用
func (s *usertokenService) Disable(token string) error {
	userToken := s.GetByToken(token)
	if userToken == nil {
		return nil
	}

	editReq := &usertokenModel.EditReq{
		Id:        userToken.Id,
		UserId:    userToken.UserId,
		Token:     userToken.Token,
		ExpiredAt: userToken.ExpiredAt,
		Status:    model.UserTokenStatusDisabled,
	}
	_, err := s.EditSave(editReq, nil)
	return err
}
